package com.module.monitor.task;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.module.admin.prj.pojo.PrjMonitor;
import com.module.admin.prj.service.PrjMonitorService;
import com.module.admin.sys.enums.SysConfigCode;
import com.module.admin.sys.service.SysConfigService;
import com.system.comm.utils.FrameHttpUtil;
import com.system.comm.utils.FrameMailUtil;
import com.system.comm.utils.FrameSpringBeanUtil;
import com.system.comm.utils.FrameStringUtil;
import com.system.comm.utils.FrameTimeUtil;

/**
 * 项目监控
 * @author yuejing
 * @date 2016年10月22日 上午9:58:59
 * @version V1.0.0
 */
public class PrjMonitorTask {

	private static final Logger LOGGER = Logger.getLogger(PrjMonitorTask.class);

	public void run() {
		LOGGER.info("========================= 初始化项目监控的任务 - 成功 ===========================");
		ScheduledExecutorService service = Executors.newScheduledThreadPool(100);
		//线程，每隔20秒调用一次
		Runnable runnable = new Runnable() {
			public void run() {
				//检测项目的信息，并写入数据库
				ThreadPoolTaskExecutor threadPoolTaskExecutor = FrameSpringBeanUtil.getBean(ThreadPoolTaskExecutor.class);
				//获取需要监控的项目
				final PrjMonitorService monitorService = FrameSpringBeanUtil.getBean(PrjMonitorService.class);
				List<PrjMonitor> monitors = monitorService.findMonitor();
				for (final PrjMonitor pm : monitors) {
					threadPoolTaskExecutor.execute(new Runnable() {
						@Override
						public void run() {
							//处理单个监控
							dealMonitor(pm);
						}

						private void dealMonitor(PrjMonitor pm) {
							String link = pm.getMonitorUrl();
							Map<String, String> params = new HashMap<String, String>();
							String content = FrameHttpUtil.post(link, params);
							/*if(LOGGER.isInfoEnabled()) {
								LOGGER.info("\n" + time + "-调用任务 ID【" + taskJob.getId() + "】名称【" + taskJob.getName() + "】\n请求地址: " + link);
							}*/
							
							//根据响应的内容做相应的记录
							if(FrameStringUtil.isNotEmpty(content) && content.trim().equalsIgnoreCase(pm.getMonitorSuccStr().trim())) {
								//监听成功
								
								//修改monitorTime和monitorStatus，修改monitorFailNum为0
								monitorService.updateMonitorSucc(pm.getPrjmId());

							} else {
								//监听失败

								int monitorFailNum = pm.getMonitorFailNum().intValue();
								monitorFailNum ++;
								
								//修改monitorTime和monitorStatus，修改monitorFailNum + 1
								monitorService.updateMonitorFail(pm.getPrjmId(), monitorFailNum);


								//判断上次发送邮件时间是否在范围内，处理是否需要发邮件
								Date mfsTime = pm.getMonitorFailSendTime();
								if(mfsTime == null) {
									mfsTime = FrameTimeUtil.getTime();
								}
								long diffNum = FrameTimeUtil.getDateDiff(mfsTime, FrameTimeUtil.getTime(), 1);
								if(pm.getMonitorFailSendTime() == null ||
										( diffNum > pm.getMonitorFailSendInterval().intValue() &&
										pm.getMonitorFailNum() != null && monitorFailNum >= pm.getMonitorFailNumRemind().intValue()
										)) {

									if(LOGGER.isInfoEnabled()) {
										LOGGER.info("检测【" + pm.getPrjName() + "-" + pm.getTypeName() + "】请求URL[ " + pm.getMonitorUrl() + " ]失败，发送邮件");
									}
									String time = FrameTimeUtil.getStrTime();
									//发送失败邮件
									StringBuilder title = new StringBuilder();
									title.append("检测项目【").append(pm.getPrjName()).append("-").append(pm.getTypeName()).append("】失败!!!");
									StringBuilder mailContent = new StringBuilder();
									mailContent.append("项目名称：").append(pm.getPrjName()).append("<br/>");
									mailContent.append("监听类型：").append(pm.getTypeName()).append("<br/>");
									mailContent.append("描述：").append(pm.getRemark()).append("<br/>");
									mailContent.append("调用时间：").append(time).append("<br/>");
									mailContent.append("调用地址：").append(link).append("<br/>");
									mailContent.append("错误原因：可能是接口地址不通，或网络不通");
									
									String toMails = pm.getMonitorFailEmail();

									SysConfigService configService = FrameSpringBeanUtil.getBean(SysConfigService.class);
									FrameMailUtil theMail = new FrameMailUtil(configService.getValue(SysConfigCode.MAIL_SMTP),
											configService.getValue(SysConfigCode.MAIL_FROM),
											configService.getValue(SysConfigCode.MAIL_USERNAME),
											configService.getValue(SysConfigCode.MAIL_PASSWORD));
									// 抄送人邮件地址
									String copyto = "";
									boolean bool = theMail.send(toMails, copyto, title.toString(), mailContent.toString());
									
									if(bool) {
										//处理其它业务（将monitorFailNum，重置为0，monitorFailSendTime修改为最新时间）
										monitorService.updateMonitorFailSendInfo(pm.getPrjmId());
									}
								}
							}

						}
					});
				}
			}
		};
		// 第二个参数为首次执行的延时时间，第三个参数为定时执行的间隔时间 
		service.scheduleAtFixedRate(runnable, 30, 20, TimeUnit.SECONDS);
	}

}
